﻿using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace kemocard.Scripts.Module.Battle;

/// <summary>
/// 动画任务队列管理器，支持从队首和队尾添加任务，并提供等待所有任务完成的异步方法
/// </summary>
public class AnimationTaskQueue
{
    private readonly Queue<Task> _taskQueue = new();
    private readonly SemaphoreSlim _semaphore = new(1, 1);
    private readonly CancellationTokenSource _cancellationTokenSource = new();
    private bool _isProcessing;

    /// <summary>
    /// 从队首添加任务
    /// </summary>
    /// <param name="task">要添加的任务</param>
    /// <param name="start">是否自动开始执行队列</param>
    public async Task EnqueueFront(Task task, bool start = false)
    {
        await _semaphore.WaitAsync();
        try
        {
            // var newTask = CreateManagedTask(task);
            var tempQueue = new Queue<Task>();
            tempQueue.Enqueue(task);

            while (_taskQueue.Count > 0)
            {
                tempQueue.Enqueue(_taskQueue.Dequeue());
            }

            foreach (var t in tempQueue)
            {
                _taskQueue.Enqueue(t);
            }

            if (start && !_isProcessing)
            {
                _isProcessing = true;
                await ProcessQueue();
            }
        }
        finally
        {
            _semaphore.Release();
        }
    }

    /// <summary>
    /// 从队尾添加任务
    /// </summary>
    /// <param name="task">要添加的任务</param>
    /// /// <param name="start">是否自动开始执行队列</param>
    public async Task EnqueueBack(Task task, bool start = false)
    {
        await _semaphore.WaitAsync();
        try
        {
            // var newTask = CreateManagedTask(task);
            _taskQueue.Enqueue(task);

            if (start && !_isProcessing)
            {
                _isProcessing = true;
                await ProcessQueue();
            }
        }
        finally
        {
            _semaphore.Release();
        }
    }

    /// <summary>
    /// 等待队列中所有任务完成（包括执行过程中新添加的任务）
    /// 执行此函数时会开始依次执行队列中的Task
    /// </summary>
    /// <returns>表示等待操作的Task</returns>
    public async Task WaitForAllTasksAsync()
    {
        // 等待直到队列为空且没有正在处理的任务
        while (true)
        {
            await _semaphore.WaitAsync();
            try
            {
                // 如果队列为空且没有正在处理的任务，则表示所有任务已完成
                if (_taskQueue.Count == 0 && !_isProcessing)
                {
                    break;
                }

                // 如果有任务但没有在处理，则开始处理
                if (_taskQueue.Count > 0 && !_isProcessing)
                {
                    _isProcessing = true;
                    // 启动处理任务但不等待（让它在后台运行）
                    _ = Task.Run(ProcessQueue);
                }
            }
            finally
            {
                _semaphore.Release();
            }

            // 短暂延迟后再次检查
            await Task.Delay(10);
        }
    }


    /// <summary>
    /// 处理队列中的任务
    /// </summary>
    private async Task ProcessQueue()
    {
        while (true)
        {
            await _semaphore.WaitAsync();
            try
            {
                if (_taskQueue.Count == 0)
                {
                    _isProcessing = false;
                    break;
                }

                var task = _taskQueue.Dequeue();
                _semaphore.Release();

                try
                {
                    // 执行任务，设置超时时间为5秒
                    var timeoutTask = Task.Delay(TimeSpan.FromSeconds(5));
                    var completedTask = await Task.WhenAny(task, timeoutTask);

                    if (completedTask == timeoutTask)
                    {
                        // 任务超时，直接丢弃并继续执行下一个任务
                        Console.WriteLine("Task timed out and was discarded");
                    }
                }
                catch (Exception)
                {
                    // 任务执行出错，直接丢弃并继续执行下一个任务
                    Console.WriteLine("Task failed and was discarded");
                }
            }
            catch (Exception)
            {
                _isProcessing = false;
                break;
            }
        }
    }

    /// <summary>
    /// 创建一个受管理的任务，确保任务完成后能正确处理队列状态
    /// </summary>
    /// <param name="taskFactory">任务工厂函数</param>
    /// <returns>包装后的任务</returns>
    private Task CreateManagedTask(Func<Task> taskFactory)
    {
        return taskFactory();
    }

    /// <summary>
    /// 销毁队列，取消所有操作
    /// </summary>
    public void Dispose()
    {
        _cancellationTokenSource.Cancel();
        _semaphore.Dispose();
        _cancellationTokenSource.Dispose();
    }

    /// <summary>
    /// 清空队列中所有任务并取消它们
    /// </summary>
    public async Task Clear()
    {
        await _semaphore.WaitAsync();
        try
        {
            // 清空队列中的所有任务
            _taskQueue.Clear();

            // 重置处理状态
            _isProcessing = false;
        }
        finally
        {
            _semaphore.Release();
        }
    }
}